package com.test.scope;

import com.test.aop.ProxyFactory;
import com.test.aop.TargetSource;
import com.test.factory.ConfigurableBeanFactory;

public class ScopedProxyFactory {
    public static Object createScopedProxy(Object targetBean, String targetBeanName, String scopeName, ConfigurableBeanFactory beanFactory) {
        if (targetBean == null){
            throw new IllegalArgumentException("目标bean为空");
        }
        ProxyFactory proxyFactory = new ProxyFactory();

        proxyFactory.setTargetSource(new ScopeTargetSource(targetBeanName, scopeName, beanFactory));

        if (targetBean.getClass().getInterfaces().length > 0){
            proxyFactory.setTargetClass(targetBean.getClass());
        }else {
            proxyFactory.setTargetClass(targetBean.getClass());
        }

        return proxyFactory.getProxy();
    }
    private static class ScopeTargetSource implements TargetSource {
        private final String scopeName;
        private final String targetBeanName;
        private final ConfigurableBeanFactory beanFactory;

        public ScopeTargetSource(String targetBeanName, String scopeName, ConfigurableBeanFactory beanFactory) {
            this.scopeName = scopeName;
            this.targetBeanName = targetBeanName;
            this.beanFactory = beanFactory;
        }
        @Override
        public Object getTarget() throws Exception {
            Scope scope = beanFactory.getRegisteredScope(scopeName);
            if (scope == null){
                throw new IllegalStateException("找不到scope：" + scopeName);
            }
            ObjectFactory<Object> objectFactory = () -> {
                return beanFactory.getBean(targetBeanName);
            };
            return scope.get(targetBeanName, objectFactory);
        }

        @Override
        public Class<?> getTargetClass() {
            try{
                return beanFactory.getType(targetBeanName);
            }catch (Exception e){
                return Object.class;
            }
        }

        @Override
        public boolean isStatic() {
            return false;
        }

        @Override
        public void releaseTarget(Object target) throws Exception {
            //不需要特别处理，作用域会自行管理对象的生命周期
        }
    }
}
